<template>
  <div class="container" @keydown.enter="gpt()">
    <div class="nav-bar">
      <a>ChatGPT</a>
      <div class="close"></div>
    </div>
    <div class="messages-area">
      <div
        class="message"
        v-for="(o, i) in qmessages"
        v-bind:key="i"
        v-show="o.role != 'system'"
        :class="{ one: o.role == 'user', two: o.role == 'assistant' }"
      >
        <el-row>
          <el-col :span="3">
            <img
              class="avatar"
              src="https://zt-1304966785.cos.ap-nanjing.myqcloud.com/啊.jpg"
              v-show="o.role == 'assistant'"
            />

            <img class="avatar" :src="userStore.avatar" v-show="o.role == 'user'" />
          </el-col>
          <el-col :span="21">
            <div v-html="getMdiText(o.content)"></div>
          </el-col>
        </el-row>
      </div>
    </div>
    <div class="sender-area">
      <div class="input-place">
        <input placeholder="Send a message." v-model="input" class="send-input" type="text" />
        <div class="send" @click="gpt()">
          <svg
            t="1710588817816"
            class="icon"
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="2480"
            width="200"
            height="200"
          >
            <path
              d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0z m249.344 776.192c-5.632 1.536-7.68 3.584-9.728 8.704-30.208 81.408-109.568 136.192-202.752 135.68-53.76-1.024-103.936-22.016-144.896-64.512-4.096-4.096-7.168-3.584-11.776-2.56-103.424 16.896-200.192-39.936-234.496-137.728-14.336-40.96-14.848-81.92-2.048-123.392 1.536-4.608 1.024-7.168-2.048-10.752-100.352-116.736-40.96-296.96 109.568-333.312 5.12-1.024 7.68-3.584 9.216-8.192 30.72-84.48 114.688-139.776 205.824-135.68 55.808 2.56 103.424 23.552 142.336 63.488 3.584 3.584 6.656 4.096 10.752 3.072 99.84-16.384 193.536 34.816 231.424 126.976 17.92 43.52 19.456 88.064 6.656 133.12-1.536 5.12-1.024 8.704 2.56 12.8 98.816 116.224 39.424 295.424-110.592 332.288z"
              fill="#059469"
              p-id="2481"
            ></path>
            <path
              d="M870.912 443.392c-3.584-4.096-4.096-7.68-2.56-12.8 13.312-45.056 11.264-89.6-6.656-133.12-37.888-92.16-131.584-143.36-231.424-126.976-4.608 0.512-7.68 0-10.752-3.072-38.912-39.936-86.016-60.928-142.336-63.488-90.624-4.096-174.592 51.2-205.824 135.68-1.536 4.608-4.096 7.168-9.216 8.192-150.016 36.352-208.896 216.576-108.544 333.312 3.072 3.584 3.584 6.656 2.048 10.752-12.8 41.472-12.288 82.432 2.048 123.392 34.304 97.792 131.072 154.112 234.496 137.728 4.096-0.512 7.68-1.536 11.776 2.56 40.96 42.496 91.648 63.488 144.896 64.512 93.184 0.512 172.544-54.272 202.752-135.68 2.048-5.12 4.096-7.68 9.728-8.704 150.016-36.352 209.408-215.552 109.568-332.288z m-51.2-98.816c3.584 15.872 3.584 32.256 2.048 48.64-0.512 5.12-1.536 6.656-7.168 3.584-51.712-30.208-103.936-59.392-155.648-89.6-14.848-8.704-27.648-9.216-43.008-0.512-58.368 34.304-117.76 67.584-176.64 100.864-2.56 1.536-5.12 3.072-8.704 4.608 0-3.072-0.512-4.608-0.512-6.144V337.408c0-4.096 1.024-6.656 5.12-8.704 51.712-29.184 103.424-59.392 155.136-88.576 93.696-50.688 207.36 1.024 229.376 104.448z m-226.304 166.912v40.96c0 4.096-1.024 6.656-4.608 8.704-24.064 13.312-48.128 27.136-72.192 40.96-3.072 2.048-5.632 2.048-9.216 0-23.552-13.824-47.616-27.136-71.168-40.96-4.096-2.56-5.632-5.12-5.632-9.728V471.552c0-4.608 1.536-7.168 5.12-9.216 24.064-13.312 47.616-27.136 71.168-40.96 3.584-2.048 6.144-2.048 9.216 0 24.064 13.824 48.128 27.648 72.192 40.96 3.584 2.048 5.12 4.608 5.12 8.704v40.448z m-279.552-199.68C314.368 235.52 365.056 174.08 440.32 159.744c47.104-8.704 89.6 3.072 128 32.768-26.112 14.848-50.688 28.672-75.776 43.008-30.72 17.408-60.928 34.816-91.648 52.224-11.264 6.144-16.384 15.36-16.384 27.648v208.384c0 8.704 0 8.704-7.68 4.608-19.456-10.752-38.4-22.016-57.856-32.768-4.096-2.56-5.632-5.12-5.632-9.728 0.512-58.368 0-116.224 0.512-174.08zM158.72 440.32c3.072-61.952 35.84-106.496 92.672-132.608 7.68-3.584 8.192-3.584 8.192 5.12v179.2c0 14.848 6.144 24.576 18.944 31.744 60.416 33.792 120.832 68.608 181.248 102.912 1.536 1.024 3.584 2.048 6.656 4.096-23.552 13.312-45.568 26.112-68.096 38.912-2.56 1.536-4.608 0.512-7.168-0.512-53.248-30.208-107.008-59.392-159.232-91.136-51.2-31.232-76.288-78.336-73.216-137.728z m68.608 293.888c-20.992-31.232-29.184-66.048-24.576-103.424 0.512-6.144 2.56-5.632 7.168-3.072 52.736 30.208 105.472 59.904 158.208 90.624 13.312 7.68 25.088 7.68 38.4 0 59.904-34.304 119.808-68.608 179.712-102.4 7.68-4.096 7.68-4.096 7.68 4.608v66.56c0 3.584-1.024 6.144-4.608 8.192-52.224 29.696-103.936 59.392-156.16 88.576-72.704 38.4-161.28 17.408-205.824-49.664z m483.328-102.912v84.992c-0.512 84.992-72.704 153.088-158.72 150.528-33.28-1.024-62.976-11.264-89.6-30.72-6.144-4.608-6.144-4.608 0.512-8.192 52.736-29.696 104.96-59.904 157.696-89.6 13.312-7.68 19.456-17.408 18.944-32.768-0.512-68.096 0-136.192 0-204.288 0-9.216 0-9.216 8.192-4.608 18.432 10.752 37.376 21.504 55.808 31.744 4.608 2.56 6.656 5.632 6.656 11.264 0 30.208 0.512 60.928 0.512 91.648z m139.264 12.288c-16.384 33.792-42.496 57.344-76.8 72.192-8.192 3.584-8.192 3.584-8.192-5.632 0-59.392-0.512-119.296 0-178.688 0-15.36-5.632-25.088-18.944-32.256-59.904-33.28-119.296-67.584-178.688-101.376-2.56-1.536-5.12-3.072-8.704-5.12 20.48-11.776 39.424-22.016 58.368-33.28 9.216-5.632 15.872-5.632 25.088 0 47.104 27.648 94.208 54.272 141.824 80.896 47.616 26.624 75.776 66.56 81.92 120.832 2.56 28.16-3.072 55.808-15.872 82.432z"
              fill="#ffffff"
              p-id="2482"
              data-spm-anchor-id="a313x.search_index.0.i3.46fd3a814FaYM5"
              class="selected"
            ></path>
            <path
              d="M430.592 338.432v68.608c0 1.536 0 3.072 0.512 6.144 3.584-2.048 6.144-3.584 8.704-4.608 58.88-33.792 117.76-66.56 176.64-100.864 15.36-8.704 27.648-8.192 43.008 0.512 51.712 30.208 103.936 59.392 155.648 89.088 5.12 3.072 6.144 1.536 7.168-3.584 1.536-16.384 1.536-32.768-2.048-48.64-22.016-103.424-135.68-155.136-228.864-103.424-52.736 28.672-103.936 58.368-156.16 88.064-3.584 2.048-4.608 4.608-4.608 8.704z"
              fill="#059469"
              p-id="2483"
            ></path>
            <path
              d="M313.344 485.376c0 4.608 1.536 7.168 5.632 9.728 19.456 10.752 38.4 22.016 57.856 32.768 7.68 4.608 7.68 4.096 7.68-4.608V314.88c0-12.288 5.12-21.504 16.384-27.648 30.72-17.408 60.928-34.816 91.648-52.224 24.576-14.336 49.664-28.16 75.776-43.008-38.4-29.696-80.896-41.472-128-32.768-74.752 13.824-125.952 75.776-126.464 152.064-0.512 58.368 0 116.224-0.512 174.08z"
              fill="#059469"
              p-id="2484"
            ></path>
            <path
              d="M390.656 669.184c2.048 1.536 4.096 2.048 7.168 0.512 22.528-12.8 44.544-25.6 68.096-38.912-3.072-1.536-4.608-3.072-6.656-4.096-60.416-34.304-120.32-68.608-181.248-102.912-12.8-7.168-18.944-16.896-18.944-31.744 0.512-59.904 0-119.296 0-179.2 0-8.704 0-8.704-8.192-5.12C194.56 334.336 161.792 378.368 158.72 440.32c-3.072 58.88 22.016 105.984 72.704 137.216 52.224 32.256 105.984 60.928 159.232 91.648zM588.288 462.336c-24.064-13.312-48.128-27.136-72.192-40.96-3.584-2.048-6.144-2.048-9.216 0-23.552 13.824-47.616 27.136-71.168 40.96-4.096 2.048-5.12 4.608-5.12 9.216v79.872c0 4.608 1.536 7.168 5.632 9.728 24.064 13.312 47.616 27.136 71.168 40.96 3.584 2.048 6.144 1.536 9.216 0 24.064-13.824 48.128-27.648 72.192-40.96 3.584-2.048 4.608-4.608 4.608-8.704v-40.96-39.936c0-4.608-1.024-7.168-5.12-9.216z"
              fill="#059469"
              p-id="2485"
            ></path>
            <path
              d="M593.408 686.08v-66.56c0-8.704 0-8.704-7.68-4.608-59.904 34.304-119.808 68.096-179.712 102.4-13.312 7.68-25.088 8.192-38.4 0l-158.208-90.624c-4.608-2.56-6.144-3.072-7.168 3.072-4.608 37.376 3.584 72.192 24.576 103.424 45.056 67.072 133.632 88.064 205.824 48.64 52.224-28.672 103.936-58.88 156.16-88.576 3.584-1.024 4.608-3.584 4.608-7.168z"
              fill="#059469"
              p-id="2486"
            ></path>
            <path
              d="M704 528.384c-18.944-10.24-37.376-20.992-55.808-31.744-8.192-4.608-8.192-4.608-8.192 4.608 0 68.096-0.512 136.192 0 204.288 0 15.36-5.632 25.088-18.944 32.768-52.736 29.696-105.472 59.392-157.696 89.6-6.656 3.584-6.656 3.584-0.512 8.192 26.624 19.456 56.32 29.696 89.6 30.72 86.016 2.56 158.208-65.536 158.72-150.528v-84.992-91.648c-0.512-5.632-2.56-8.704-7.168-11.264z"
              fill="#059469"
              p-id="2487"
              data-spm-anchor-id="a313x.search_index.0.i2.46fd3a814FaYM5"
              class=""
            ></path>
            <path
              d="M783.36 439.808c-47.616-26.624-94.72-53.248-141.824-80.896-9.216-5.632-15.872-5.632-25.088 0-18.432 11.776-37.888 22.016-58.368 33.28 3.584 2.048 6.144 3.584 8.704 5.12 59.392 33.792 118.784 68.096 178.688 101.376 13.312 7.68 18.944 17.408 18.944 32.256-0.512 59.392 0 118.784 0 178.688 0 9.216 0 9.216 8.192 5.632 34.304-14.848 60.416-38.912 76.8-72.192 12.8-26.112 18.944-53.76 15.36-82.944-5.632-53.76-33.792-93.184-81.408-120.32z"
              fill="#059469"
              p-id="2488"
            ></path>
          </svg>
        </div>
      </div>
    </div>
    <div></div>
  </div>
</template>

<script setup>
import { ref, reactive, toRefs, onMounted, nextTick } from 'vue';
import MarkdownIt from 'markdown-it';

import hljs from 'highlight.js';
import 'highlight.js/styles/atom-one-dark.min.css';

import { useUserStore } from '@/stores/userinfo';
// 引入相关样式

const userStore = ref(useUserStore());
const qmessages = ref([
  {
    role: 'system',
    content:
      '\nYou are ChatGPT, a large language model trained by OpenAI.\nKnowledge cutoff: 2023-04\nCurrent model: gpt-4-all\nCurrent time: 2024/1/14 21:51:51\nLatex inline: $x^2$ \nLatex block: $$e=mc^2$$\n\n',
  },
]);
const mdi = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true,
  highlight(str, lang) {
    // 当前时间加随机数生成唯一的id标识
    const codeIndex = parseInt(Date.now()) + Math.floor(Math.random() * 10000000);
    // 复制功能主要使用的是 clipboard.js
    let html = `<button class="copy-btn p-2" type="button" data-clipboard-action="copy" data-clipboard-target="#copy${codeIndex}"  onclick="copyCode('copy${codeIndex}')">复制</button>`;
    const linesLength = str.split(/\n/).length - 1;
    // 生成行号
    let linesNum = '<span aria-hidden="true" class="line-numbers-rows">';
    for (let index = 0; index < linesLength; index++) {
      linesNum += '<span></span>';
    }
    linesNum += '</span>';
    if (lang && hljs.getLanguage(lang)) {
      try {
        // highlight.js 高亮代码
        const preCode = hljs.highlight(lang, str, true).value;
        html += preCode;
        if (linesLength) {
          html += `<b class="name  p-2">${lang}</b>`;
        }
        // 将代码包裹在 textarea 中
        return `<pre class="hljs"><code>${html}</code>${linesNum}</pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy${codeIndex}">${str.replace(
          /<\/textarea>/g,
          '&lt;/textarea>',
        )}</textarea>`;
      } catch (error) {
        console.log(error);
      }
    }

    const preCode = mdi.utils.escapeHtml(str);
    html += preCode;
    // 将代码包裹在 textarea 中
    return `<pre class="hljs"><code>${html}</code>${linesNum}</pre><textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy${codeIndex}">${str.replace(
      /<\/textarea>/g,
      '&lt;/textarea>',
    )}</textarea>`;
  },
});

function getMdiText(value) {
  return mdi.render(value);
}
const clipboard = ref('');
const input = ref('');
async function gpt() {
  qmessages.value.push({
    role: 'user',
    content: input.value,
  });
  const response = await fetch('/yzam/chat/completions', {
    method: 'POST',
    headers: {
      Authorization: `Bearer sk-Wza31MksVicYvfMjDLEAMcCP1S3htPXNrB6LYE5peSxB5mWp`,
      'Content-Type': 'application/json',
      // 其他需要的头部信息
    },
    body: JSON.stringify({
      messages: qmessages.value,
      model: 'moonshot-v1-128k',
      // presence_penalty: 0,
      stream: true,

      top_p: 1,
      temperature: 0.3,
      presence_penalty: 0.6,
      frequency_penalty: 0,
      // session_id: new Date()
    }),
  });
  console.log('response', response);
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  let currentMessage = '';
  qmessages.value.push({
    role: 'assistant',
    content: currentMessage,
  });
  // console.log(response)
  const reader = response.body.getReader();
  while (true) {
    const { value, done } = await reader.read();

    if (done) {
      console.log('done.');
      // console.log(list);
      console.log('done', qmessages.value);

      break; // 读取完毕
    } else {
      const dataText = new TextDecoder().decode(value);
      const data = dataText.split('\n\n').filter(Boolean);
      // console.log('message: ', new TextDecoder().decode(value));
      // console.log(data);
      // console.log('list', list)
      data.forEach(function (element) {
        // console.log('element', element)
        if (element.startsWith('data: ') && !element.includes('[DONE]')) {
          try {
            const line = JSON.parse(element.replace('data: ', ''));
            // console.log('line', line)
            if (
              line.choices[0].delta.role != 'assistant' &&
              line.choices[0].delta.content != null &&
              line.choices[0].delta.content != ''
            ) {
              currentMessage += line.choices[0].delta.content;
              // console.log('currentMessage', currentMessage)
              qmessages.value[qmessages.value.length - 1].content = currentMessage;
            }
          } catch (error) {
            console.error('JSON parsing error:', error);
          }
        }
      });

      // list.forEach(function (element) {
      //     if (element.choices[0].delta.role != "assistant" && element.choices[0].delta.content != null) {
      //         that.currentMessage += element.choices[0].delta.content;
      //     }

      // });
      // console.log(that.currentMessage);

      // var data = new TextDecoder().decode(value);
      // this.messages.push(data.data.choices[0].delta.content);
    }
  }
}
</script>
<style lang="less">
pre.hljs {
  position: relative;
  padding: 12px 2px 12px 40px !important;
  overflow: hidden !important;
  font-size: 14px !important;
  line-height: 22px !important;
  border-radius: 5px !important;

  code {
    display: block !important;
    margin: 0 10px !important;
    overflow-x: auto !important;
  }

  .line-numbers-rows {
    position: absolute;
    top: 12px;
    bottom: 12px;
    left: 0;
    width: 40px;
    font-size: 100%;
    text-align: center;
    letter-spacing: -1px;
    pointer-events: none;
    counter-reset: linenumber;
    user-select: none;
    border-right: 1px solid rgb(0 0 0 / 66%);

    span {
      display: block;
      pointer-events: none;
      counter-increment: linenumber;

      &::before {
        display: block;
        color: #999;
        text-align: center;
        content: counter(linenumber);
      }
    }
  }

  b.name {
    position: absolute;
    top: 2px;
    right: 60px;
    z-index: 10;
    color: #999;
    pointer-events: none;
  }

  .copy-btn {
    position: absolute;
    top: 2px;
    right: 4px;
    z-index: 10;
    color: #333;
    cursor: pointer;
    background-color: #fff;
    border: 0;
    border-radius: 2px;
  }
}
</style>
<style scoped lang="less">
.avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
}

.container {
  width: 96%;
  height: 88vh;
  background-color: #343541;
  border-radius: 8px;
  display: flex;
  flex-direction: column;
}

.nav-bar {
  width: 100%;
  height: 40px;
  background-color: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.nav-bar a {
  color: #6b6c7b;
  white-space: nowrap;
  margin-left: 10px;
  user-select: none;
}

.close {
  width: 40px;
  height: 40px;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  cursor: pointer;
}

.line {
  position: absolute;
  width: 20px;
  height: 3px;
  background-color: #6b6c7b;
  border-radius: 30px;
}

.line.one {
  transform: rotate(45deg);
}

.line.two {
  transform: rotate(135deg);
}

.messages-area {
  width: 100%;
  height: 80vh;
  max-height: 80vh;
  overflow: auto;
}

.sender-area {
  background-color: #343541;
  width: 100%;
  height: 70px;
  display: flex;
  border-radius: 8px;
}

.message {
  width: 100%;

  text-align: left;
  padding: 20px;
}

.message.one,
.message.three,
.message.five {
  background-color: #2e2f3a;
}

.message.two,
.message.four,
.message.six {
  background-color: #343541;
}

.send-img {
  width: 30px;
}

.send-input {
  outline: none;
  display: flex;
  border: none;
  background: none;
  height: 40px;
  width: 90%;
  border-radius: 7px;
  background: none;
  color: white;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  margin-left: 5px;
}

.send-input::placeholder {
  color: #828e9e;
}

.input-place {
  display: flex;
  flex-direction: row;
  margin-top: 15px;
  margin-left: 10px;
  align-items: center;
  background-color: #40414f;
  border-radius: 7px;
  height: 40px;
  width: 96%;
  gap: 5px;
  border: 1px solid #2e2f3a;
}

.send {
  width: 30px;
  height: 30px;
  background-color: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  animation: rotate 5s infinite;
}

@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

.send:hover {
  animation-play-state: paused;
}

.send-icon {
  width: 17px;
}
</style>
